/**
 * 服务注册器类
 * 负责管理服务的注册、发现和生命周期
 */
class ServiceRegistry {
  constructor() {
    this.services = new Map();
    this.aliases = new Map();
    this.serviceGroups = new Map();
  }

  /**
   * 注册服务
   * @param {string} name - 服务名称
   * @param {Function|Object} service - 服务构造函数或实例
   * @param {Object} options - 服务选项
   * @returns {ServiceRegistry} 当前实例，支持链式调用
   */
  register(name, service, options = {}) {
    if (this.services.has(name)) {
      console.warn(`Service ${name} is already registered, overriding...`);
    }

    this.services.set(name, {
      name,
      service,
      options,
      registeredAt: Date.now()
    });

    // 如果有分组，添加到分组
    if (options.group) {
      this.addToGroup(options.group, name);
    }

    // 如果有别名，注册别名
    if (options.alias) {
      const aliases = Array.isArray(options.alias) ? options.alias : [options.alias];
      aliases.forEach(alias => {
        this.aliases.set(alias, name);
      });
    }

    return this;
  }

  /**
   * 批量注册服务
   * @param {Object} services - 服务对象，键为服务名称，值为{service, options}对象
   * @returns {ServiceRegistry} 当前实例，支持链式调用
   */
  registerAll(services) {
    for (const [name, config] of Object.entries(services)) {
      if (typeof config === 'function' || typeof config === 'object' && !config.service) {
        // 简化格式：name: service
        this.register(name, config);
      } else {
        // 完整格式：name: {service, options}
        this.register(name, config.service, config.options);
      }
    }
    return this;
  }

  /**
   * 获取服务配置
   * @param {string} name - 服务名称或别名
   * @returns {Object|null} 服务配置或null
   */
  getServiceConfig(name) {
    // 检查别名
    const realName = this.aliases.get(name) || name;
    return this.services.get(realName) || null;
  }

  /**
   * 检查服务是否已注册
   * @param {string} name - 服务名称或别名
   * @returns {boolean} 是否已注册
   */
  has(name) {
    return this.aliases.has(name) || this.services.has(name);
  }

  /**
   * 注销服务
   * @param {string} name - 服务名称
   * @returns {ServiceRegistry} 当前实例，支持链式调用
   */
  unregister(name) {
    // 移除别名引用
    for (const [alias, realName] of this.aliases.entries()) {
      if (realName === name) {
        this.aliases.delete(alias);
      }
    }

    // 从分组中移除
    for (const [group, services] of this.serviceGroups.entries()) {
      const index = services.indexOf(name);
      if (index !== -1) {
        services.splice(index, 1);
      }
    }

    // 移除服务
    this.services.delete(name);
    return this;
  }

  /**
   * 注册服务别名
   * @param {string} alias - 别名
   * @param {string} serviceName - 服务名称
   * @returns {ServiceRegistry} 当前实例，支持链式调用
   */
  alias(alias, serviceName) {
    if (!this.services.has(serviceName)) {
      throw new Error(`Cannot create alias for non-existent service: ${serviceName}`);
    }
    this.aliases.set(alias, serviceName);
    return this;
  }

  /**
   * 添加服务到分组
   * @param {string} group - 分组名称
   * @param {string} serviceName - 服务名称
   * @returns {ServiceRegistry} 当前实例，支持链式调用
   */
  addToGroup(group, serviceName) {
    if (!this.serviceGroups.has(group)) {
      this.serviceGroups.set(group, []);
    }
    
    const groupServices = this.serviceGroups.get(group);
    if (!groupServices.includes(serviceName)) {
      groupServices.push(serviceName);
    }
    
    return this;
  }

  /**
   * 获取分组中的所有服务名称
   * @param {string} group - 分组名称
   * @returns {string[]} 服务名称数组
   */
  getGroupServices(group) {
    return this.serviceGroups.get(group) || [];
  }

  /**
   * 获取所有服务名称
   * @returns {string[]} 服务名称数组
   */
  getServiceNames() {
    return Array.from(this.services.keys());
  }

  /**
   * 获取所有服务别名
   * @returns {Map} 别名映射
   */
  getAliases() {
    return new Map(this.aliases);
  }

  /**
   * 获取所有服务组
   * @returns {Map} 服务组映射
   */
  getGroups() {
    return new Map(this.serviceGroups);
  }

  /**
   * 清空所有服务注册
   * @returns {ServiceRegistry} 当前实例，支持链式调用
   */
  clear() {
    this.services.clear();
    this.aliases.clear();
    this.serviceGroups.clear();
    return this;
  }
}

export default ServiceRegistry;